package no.uio.ifi.cop.prover.factorder;

import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;

import no.uio.ifi.cop.common.Global;

/**
 * A map that returns elements in random order.
 *
 *
 * @version 1.0
 * @author  bjarneh@ifi.uio.no
 */

public final class RandomMap<K,V> extends HashMap<K,V> {

    private Random random;
    private List<K> keyList;

    public RandomMap(){
        super();
        init(200);
    }

    public RandomMap(int initialCapacity){
        super(initialCapacity);
        init(initialCapacity);
    }

    public RandomMap(int initialCapacity, float loadFactor){
        super(initialCapacity, loadFactor);
        init(initialCapacity);
    }

    public RandomMap(Map<? extends K,? extends V> m){
        super(m);
        init(200);
    }

    protected void init(int capacity){
        keyList = new ArrayList<K>(capacity);
        random = new Random(Global.getLong("-seed"));
    }

    public void clear(){
        super.clear();
        keyList.clear();
    }

    public V put(K key, V value){
        if(keyList.contains(key)){
            return value;
        }
        keyList.add(key);
        return super.put(key, value);
    }

    public V remove(Object key){
        keyList.remove(key);
        return super.remove(key);
    }

    public Collection<V> values(){
        Collections.shuffle(keyList, random);
        ArrayList<V> vals = new ArrayList<V>(keyList.size());
        for(K key: keyList) {
            vals.add( get(key) );
        }
        return vals;
    }

    public Collection<V> unshuffled(){
        ArrayList<V> vals = new ArrayList<V>(keyList.size());
        for(K key: keyList) {
            vals.add( get(key) );
        }
        return vals;
    }
}
